package com.example.demo.util;

import com.example.demo.util.ssl.EasyX509TrustManger;
import com.example.demo.util.ssl.SimpleKeyStoreTrustManager;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.InputStream;
import java.security.KeyStore;

public class SSLUtils {

    private static final String PWD_EASYSERVER_KEYSTORE = "123456";

    private static final String PWD_EASYERVER_KEY = "123456";


    public static SSLContext getServerSSLContext() {
        InputStream is = SSLUtils.class.getResourceAsStream("server.jks");
        try {
            KeyStore ks = KeyStore.getInstance("JKS");

            ks.load(is, PWD_EASYSERVER_KEYSTORE.toCharArray());

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(ks, PWD_EASYERVER_KEY.toCharArray());

            TrustManager easyTM = new EasyX509TrustManger();
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(kmf.getKeyManagers(), new TrustManager[]{easyTM}, null);

            return context;
        } catch (Exception e) {
            throw new RuntimeException("sslcontext init failed!");
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    public static SSLContext getClientSSLContext(KeyStore keyKs, char[] keypwd, KeyStore certKs, String protocal) {
        try {

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyKs, keypwd);

            TrustManager[] trusts = new TrustManager[]{
                    new SimpleKeyStoreTrustManager(certKs)
            };

            return getClientSSLContext(kmf.getKeyManagers(), trusts, protocal);
        } catch (Exception e) {
            throw new RuntimeException("sslcontext init failed!");
            //throw new AppRTException(AppExCode.CREATE_SSLCONTEXT_FAILED, "sslcontext init failed!",e);
        }
    }

    public static SSLContext getClientSSLContext(KeyStore keyKs, char[] keypwd, KeyStore certKs) {
        return getClientSSLContext(keyKs, keypwd, certKs, "SSL");
    }


    public static SSLContext getClientSSLContext(KeyStore keyKs, char[] keypwd, TrustManager[] trustManagers, String protocal) {
        try {

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyKs, keypwd);

            return getClientSSLContext(kmf.getKeyManagers(), trustManagers, protocal);
        } catch (Exception e) {
            throw new RuntimeException("sslcontext init failed!");
            //throw new AppRTException(AppExCode.CREATE_SSLCONTEXT_FAILED, "sslcontext init failed!",e);
        }
    }

    public static SSLContext getClientSSLContext(KeyStore keyKs, char[] keypwd, TrustManager[] trustManagers) {
        return getClientSSLContext(keyKs, keypwd, trustManagers, "SSL");
    }


    public static SSLContext getClientSSLContext(KeyManager[] keyManagers, TrustManager[] trustManagers) {
        return getClientSSLContext(keyManagers, trustManagers, "SSL");
    }

    public static SSLContext getClientSSLContext(KeyManager[] keyManagers, TrustManager[] trustManagers, String protocal) {
        try {
            SSLContext context = SSLContext.getInstance(protocal);
            context.init(keyManagers, trustManagers, null);
            return context;
        } catch (Exception e) {
            throw new RuntimeException("sslcontext init failed!");
            //throw new AppRTException(AppExCode.CREATE_SSLCONTEXT_FAILED, "sslcontext init failed!",e);
        }
    }


}
